<template>
  <el-form label-width="100px">
    <el-form-item label="SPU名称">
      <el-input
                placeholder="请输入SPU名称"
                v-model="SpuParams.spuName"></el-input>
    </el-form-item>
    <el-form-item label="SPU品牌">
      <el-select placeholder="请选择SPU品牌" v-model="SpuParams.tmId">
        <el-option
                   :label="item.tmName"
                   v-for="item in AllTradeMark"
                   :key="item.id"
                   :value="item.tmName"></el-option>
      </el-select>
    </el-form-item>
    <el-form-item label="SPU描述">
      <el-input
                type="textarea"
                v-model="SpuParams.description"
                placeholder="请输入SPU描述"></el-input>
    </el-form-item>
    <el-form-item label="SPU照片">
      <!-- v-model:file-list 展示默认图片
                action 上传图片的接口地址
                list-type 展示类型
                :on-preview 预览图片钩子
                :on-remove 删除图片钩子
            -->
      <el-upload
                 v-model:file-list="imgList as UploadUserFile[]"
                 action="/api/admin/product/fileUpload"
                 list-type="picture-card"
                 :on-preview="handlePictureCardPreview"
                 :on-remove="handleRemove"
                 :before-upload="handleUpload">
        <el-icon>
          <Plus />
        </el-icon>
      </el-upload>

      <el-dialog v-model="dialogVisible">
        <img
             w-full
             style="width: 100%; height: 100%"
             :src="dialogImageUrl"
             alt="Preview Image" />
      </el-dialog>
    </el-form-item>
    <el-form-item label="SPU销售属性">
      <el-select
                 style="width: 100px;"
                 v-model="saleAttrAndValueName"
                 :placeholder="unSelectSaleAttr.length ? `可选${unSelectSaleAttr.length}个` : '无'
                   ">
        <el-option
                   v-for="item in unSelectSaleAttr"
                   :key="item.id"
                   :label="item.name"
                   :value="`${item.id}:${item.name}`"></el-option>
      </el-select>
      <el-button
                 style="margin-left: 10px"
                 type="primary"
                 size="default"
                 icon="Plus"
                 @click="addSaleAttr"
                 :disabled="!saleAttrAndValueName">添加属性</el-button>
      <!-- 展示销售属性和属性值 -->
      <el-table border :data="saleAttrList" style="margin: 10px 0">
        <el-table-column
                         label="序号"
                         type="index"
                         align="center"
                         width="80px"></el-table-column>
        <el-table-column
                         label="销售属性名"
                         width="100px"
                         align="center"
                         prop="saleAttrName"></el-table-column>
        <el-table-column label="销售属性值">
          <template #="{ row }">
            <el-tag
                    v-for="(item, index) in row.spuSaleAttrValueList"
                    :key="item.id"
                    class="mr-1"
                    closable
                    @close="row.spuSaleAttrValueList.splice(index, 1)">
              {{ item.saleAttrValueName }}
            </el-tag>
            <el-input
                      v-if="row.isEdit"
                      v-model="row.saleAttrValue"
                      placeholder="请输入属性值"
                      size="small"
                      style="width: 100px"
                      @blur="toLook(row)"></el-input>
            <el-button
                       v-else
                       type="primary"
                       size="small"
                       icon="Plus"
                       @click="toEdit(row)"></el-button>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="100px" align="center">
          <template #="{ $index }">
            <el-button
                       type="danger"
                       size="small"
                       icon="Delete"
                       @click="saleAttrList.splice($index, 1)"></el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-button
                 :disabled="saleAttrList.length === 0 ? true : false"
                 type="primary"
                 size="default"
                 @click="save">保存</el-button>
      <el-button size="default" @click="cancel">取消</el-button>
    </el-form-item>
  </el-form>
</template>

<script setup lang="ts">
import { ref, computed } from "vue";
import { UploadUserFile } from "element-plus/lib/components/upload/src/upload.js";
import {
  reqAllTrademark,
  reqSpuImageList,
  reqAllSaleAttr,
  reqSpuHasSaleAttr,
  reqAddOrUpdateSpu,
} from "@/api/product/spu";
// 引入ts类型
import type {
  SPUData,
  AllTrademark,
  SpuHasImg,
  HasSaleAttrResponseData,
  SaleAttrResponseData,
  Trademark,
  SPUImage,
  HasSaleAttr,
  SaleAttr,
  SaleAttrValue,
} from "@/api/product/spu/type";
import { ElMessage } from "element-plus";
// 定义自定义事件
const $emit = defineEmits(["changeScene"]);
// 存储SPU数据
const AllTradeMark = ref<Trademark[]>([]);
const imgList = ref<SPUImage[]>([]);
const saleAttrList = ref<SaleAttr[]>([]);
const hasSaleAttr = ref<HasSaleAttr[]>([]);
// 控制对话框的显示与隐藏效果
const dialogVisible = ref<boolean>(false);
// 控制对话框显示的图片
const dialogImageUrl = ref<string>("");
// 收集还未选择的销售属性的id和名称
const saleAttrAndValueName = ref<string>("");

// 存储已有的SPU对象
const SpuParams = ref<SPUData>({
  category3Id: "", // 三级分类id
  spuName: "", // spu名称
  description: "", // 描述
  tmId: "", // 品牌id
  spuImageList: [],
  spuSaleAttrList: [],
});

// 点击取消按钮
const cancel = () => {
  // 触发自定义事件,通知父组件切换场景
  $emit("changeScene", { flag: 0, params: "update" });
};

const initHasSpuData = async (row: SPUData) => {
  // row 为 父组件传递的spu对象[不完整]
  SpuParams.value = row;
  // 获取全部品牌的数据
  const result1: AllTrademark = await reqAllTrademark();
  // 获取某个品牌下售卖商品的图片
  const result2: SpuHasImg = await reqSpuImageList(row.id as number);
  // 获取已有SPU的销售属性
  const result3: SaleAttrResponseData = await reqSpuHasSaleAttr(
    row.id as number,
  );
  // 获取所有的SPU销售属性
  const result4: HasSaleAttrResponseData = await reqAllSaleAttr();
  // 存储已有SPU的数据
  AllTradeMark.value = result1.data;
  imgList.value = result2.data.map((item) => {
    return {
      name: item.imgName,
      url: item.imgUrl,
    };
  });
  saleAttrList.value = result3.data;
  hasSaleAttr.value = result4.data;
};

// 照片墙预览钩子
const handlePictureCardPreview = (file: any) => {
  dialogImageUrl.value = file.url;
  // 对话框弹出
  dialogVisible.value = true;
};

// 照片墙删除钩子
const handleRemove = () => { };

// 照片墙上传之前的钩子（可以约束文件类型）
const handleUpload = (file: any) => {
  if (
    file.type === "image/jpeg" ||
    file.type === "image/png" ||
    file.type === "image/gif"
  ) {
    if (file.size / 1024 / 1024 < 3) {
      return true;
    } else {
      ElMessage({
        type: "error",
        message: "图片大小不能超过3M",
      });
      return false;
    }
  } else {
    ElMessage({
      type: "error",
      message: "上传的图片格式不正确",
    });
    return false;
  }
};

// 计算当前SPU还未拥有的销售属性
const unSelectSaleAttr = computed(() => {
  const unSelectArr = hasSaleAttr.value.filter((item) => {
    return saleAttrList.value.every((item1) => {
      return item1.saleAttrName !== item.name;
    });
  });
  return unSelectArr;
});

// 添加销售属性的方法
const addSaleAttr = () => {
  const [baseSaleAttrId, saleAttrName] = saleAttrAndValueName.value.split(":");
  // 准备销售属性对象
  const newSaleAttr: SaleAttr = {
    baseSaleAttrId,
    saleAttrName,
    spuSaleAttrValueList: [],
  };
  // 追加到数组当中
  saleAttrList.value.push(newSaleAttr);
  // 添加完成后清空收集的数据
  saleAttrAndValueName.value = "";
};

// 添加属性值按钮点击事件回调
const toEdit = (row: SaleAttr) => {
  row.isEdit = true;
  row.saleAttrValue = "";
};

// 表单元素失去焦点事件的回调
const toLook = (row: SaleAttr) => {
  // 收集属性id和属性值名称
  const { baseSaleAttrId, saleAttrValue } = row;
  const newSaleAttrValue: SaleAttrValue = {
    baseSaleAttrId,
    saleAttrValueName: saleAttrValue as string,
  };
  // 非空判断
  if ((saleAttrValue as string).trim() === "") {
    ElMessage({
      type: "error",
      message: "属性值不能为空",
    });
    return;
  }

  // 重复判断
  const repeat = row.spuSaleAttrValueList.find((item) => {
    return item.saleAttrValueName === saleAttrValue;
  });
  if (repeat) {
    ElMessage({
      type: "error",
      message: "属性值不能重复",
    });
    return;
  }

  row.spuSaleAttrValueList.push(newSaleAttrValue);
  // 切换为查看模式
  row.isEdit = false;
};

// 保存按钮的回调
const save = async () => {
  // 整理参数
  // 照片墙数据
  SpuParams.value.spuImageList = imgList.value.map((item: any) => {
    return {
      imgName: item.name,
      imgUrl: (item.response && item.response.data) || item.url,
    };
  });
  // 销售属性数据
  SpuParams.value.spuSaleAttrList = saleAttrList.value;
  const result = await reqAddOrUpdateSpu(SpuParams.value);
  if (result.code === 200) {
    ElMessage({
      type: "success",
      message: SpuParams.value.id ? "修改成功" : "添加成功",
    });
    // 更新成功，通知父组件切换场景
    $emit("changeScene", {
      flag: 0,
      params: SpuParams.value.id ? "update" : "add",
    });
  } else {
    ElMessage({
      type: "error",
      message: SpuParams.value.id ? "修改失败" : "添加失败",
    });
  }
};

// 添加新的SPU初始化请求方法
const initAddSpu = async (c3Id: number | string) => {
  // 清空数据
  Object.assign(SpuParams.value, {
    category3Id: "", // 三级分类id
    spuName: "", // spu名称
    description: "", // 描述
    tmId: "", // 品牌id
    spuImageList: [],
    spuSaleAttrList: [],
  });
  imgList.value = [];
  saleAttrList.value = [];
  saleAttrAndValueName.value = "";
  // 存储三级分类的id
  SpuParams.value.category3Id = c3Id;
  // 获取全部品牌的数据
  const result1: AllTrademark = await reqAllTrademark();
  // 获取所有的SPU销售属性
  const result2: HasSaleAttrResponseData = await reqAllSaleAttr();
  // 存储数据
  AllTradeMark.value = result1.data;
  hasSaleAttr.value = result2.data;
};

// 对外暴露
defineExpose({ initHasSpuData, initAddSpu });
</script>

<style scoped lang="scss">
.mr-1 {
  margin-right: 4px;
}
</style>
